package com.modifiertech.lineage.client.gui.ftbint;

import com.feed_the_beast.ftblib.lib.gui.*;
import com.feed_the_beast.ftblib.lib.util.misc.MouseButton;
import com.modifiertech.lineage.BaseConst;
import com.modifiertech.lineage.Lineage;
import com.modifiertech.lineage.LineageRegistries;
import com.modifiertech.lineage.api.PlayerData;
import com.modifiertech.lineage.api.PlayerDataSkill;
import com.modifiertech.lineage.event.PlayerDataHandler;
import com.modifiertech.lineage.network.MessageSkillModify;
import com.modifiertech.lineage.network.NetworkHandler;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

/**技能面板技能按钮
 *
 */
public class BtnSkillV2 extends Button {
    //上层技能面板关联
    private PanelSkillV2 relPanelSkill;
    //上层技能页底部描述栏
    private PanelFootV2 relPanelFootV2;
    //上层技能数据存储对象
    public PlayerDataSkill skillInfo;
    //上层玩家数据存储对象
    public PlayerData playerDataRelClient;
    //上层技能页主GUI
    private GuiLineageV2 mainGui;
    //技能等级相关描述
    private TextField relLevelTextField;
    //技能等级+ 按钮
    private SkillLevelOptBtn relLevelAddBtn;
    //技能等级- 按钮
    private SkillLevelOptBtn relLevelSubBtn;

    public PanelSkillV2 getRelPanelSkill() {
        return relPanelSkill;
    }

    public void setRelPanelSkill(PanelSkillV2 relPanelSkill) {
        this.relPanelSkill = relPanelSkill;
    }

    public SkillLevelOptBtn getRelLevelAddBtn() {
        return relLevelAddBtn;
    }

    public void setRelLevelAddBtn(SkillLevelOptBtn relLevelAddBtn) {
        this.relLevelAddBtn = relLevelAddBtn;
    }

    public SkillLevelOptBtn getRelLevelSubBtn() {
        return relLevelSubBtn;
    }

    public void setRelLevelSubBtn(SkillLevelOptBtn relLevelSubBtn) {
        this.relLevelSubBtn = relLevelSubBtn;
    }

    /**技能等级操作按钮
     *
     */
    public class SkillLevelOptBtn extends Button{
        BtnSkillV2 btnSkillV2;
        private int type;//1:+ 0:-
        private volatile boolean isActive=true;
        public SkillLevelOptBtn(Panel panel, int type, BtnSkillV2 btnSkillV2) {
            super(panel);
            this.type=type;
            this.btnSkillV2=btnSkillV2;
            if(0==type){
                this.setIcon(GuiIconsV2.SUB);
            }else if(1==type){
                this.setIcon(GuiIconsV2.ADD);
            }
        }

        @Override
        public void onClicked(MouseButton button) {
            if(0==type){
                skillSubTemp();
            }else if(1==type){
                skillAddTemp();
            }else{}
        }

        @Override
        public boolean mousePressed(MouseButton button) {
            if (isMouseOver())
            {
                if (getWidgetType() != WidgetType.DISABLED)
                {
                    ExecutorService executorService= Executors.newSingleThreadExecutor();
                    isActive=true;
                    onClicked(button);
                    executorService.submit(()->{
                        int i=0;
                        while (true){
                            long sleepTime=i<=5?200:
                                    50;
                            try {
                                Thread.sleep(sleepTime);
                                i++;
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } if (!isActive)break;
                            onClicked(button);
                        }
                    });
                }
                return true;
            }
            return false;
        }
        @Override
        public void mouseReleased(MouseButton button) {
            super.mouseReleased(button);
            isActive=false;
        }


//        @Override
//        public void mouseReleased(MouseButton button) {
//            super.mouseReleased(button);
//        }

        @Override
        public void tick() {
            super.tick();
            renderRelLevelText();
        }

        /**客户端,增加临时技能属性
         *
         */
        public synchronized void skillAddTemp(){
            int optCount =skillInfo.getUpgradeCount();//对应技能每升一级需要的点数

            //当前已经分配的点数集合
            int countTemp =0;
            for (Map.Entry<String, Integer> stringIntegerEntry : relPanelSkill.getSkillTempCount().entrySet()) {
                //获取技能类型实例
                Optional<PlayerDataSkill> playerDataSkill =playerDataRelClient.getPlayerDataSkillByName(stringIntegerEntry.getKey());
                if (playerDataSkill.isPresent()){
                    //获取技能占用点数
                    countTemp+=(playerDataSkill.get().getUpgradeCount())*stringIntegerEntry.getValue();
                }
            }
            int count=countTemp+optCount;
            if(count>playerDataRelClient.getSkillPointUndistributed())return;
            if(!relPanelSkill.getSkillTempCount().containsKey(skillInfo.getSkillName())){
                relPanelSkill.getSkillTempCount().put(skillInfo.getSkillName(),1);
            }else{
                relPanelSkill.getSkillTempCount().put(skillInfo.getSkillName(),
                        relPanelSkill.getSkillTempCount().get(skillInfo.getSkillName())+1);
            }
            renderRelLevelText();
        }

        /**客户端,扣减临时技能属性
         *
         */
        public synchronized void skillSubTemp(){
            int count=relPanelSkill.getSkillTempCount().values().stream().mapToInt(v->v).sum();
            if(count==0)return;
            if(!relPanelSkill.getSkillTempCount().containsKey(skillInfo.getSkillName()))return;
            relPanelSkill.getSkillTempCount().put(skillInfo.getSkillName(),
                        relPanelSkill.getSkillTempCount().get(skillInfo.getSkillName())-1);
            renderRelLevelText();
        }

        @Override
        public boolean shouldDraw() {
            //1.can draw
            if(playerDataRelClient.getSkillPointUndistributed()< 1)return false;
            if(skillInfo.getLevelDependency()>playerDataRelClient.getLevel())return false;
            //ADD
            if(1==type){
                    //check skill
                    List<String> checkSkill=skillInfo.getSkillsDependencyName();
                    //可加的点数不满足技能所需点数
                    if (playerDataRelClient.getSkillPointUndistributed()<skillInfo.getUpgradeCount())return false;
                    if(checkSkill.isEmpty())return true;
                for (String s : checkSkill) {
                    String[] str=s.split(":");
                    boolean attach=false;

                    for (PlayerDataSkill playerDataSkill : playerDataRelClient.getAllPlayerDataSkills()) {
                        if(str[0].equals(playerDataSkill.getSkillName())){
                            attach=true;
                            if(str.length>1){
                                if(Integer.parseInt(str[1])>playerDataSkill.getSkillLevel())return false;
                            }else{
                                if(0==playerDataSkill.getSkillLevel())return false;
                            }
                        }
                    }
                    if (!attach)return false;
                }
                //all valid
                return true;
            }else if(0== type){
                if(relPanelSkill.hasSkillInTemp(skillInfo.getSkillName()))return true;
            }else{
                return false;
            }
            return false;
        }
    }


    public TextField getRelLevelTextField() {
        return relLevelTextField;
    }


    public BtnSkillV2(Panel panel, String t
            ,PanelFootV2 relPanelFootV2,PlayerDataSkill skillInfo,GuiLineageV2 mainGui,TextField textField,PanelSkillV2 relPanelSkill) {
        super(panel, t, skillInfo.getIcon());
        this.relPanelSkill=relPanelSkill;
        this.relPanelFootV2=relPanelFootV2;
        this.skillInfo=skillInfo;
        this.mainGui=mainGui;
        this.relLevelTextField=textField;
        this.relLevelAddBtn=new SkillLevelOptBtn(panel,1,this);
        this.relLevelSubBtn=new SkillLevelOptBtn(panel,0,this);
        init();
    }

//    @Override
//    public void drawBackground(Theme theme, int x, int y, int w, int h) {
////        Color4I.BLACK.withAlpha(10).draw(x, y, w, h);
//    }

    private void init() {
        initPlayerData();
        relLevelTextField.setText("Lv "+skillInfo.getSkillLevel());
        relLevelTextField.setScale(0.75f);
    }

    /**渲染技能对应等级描述信息
     *
     */
    public void renderRelLevelText(){
        String textPre="Lv ";
        String level=skillInfo.getSkillLevel()+"";

        String temp=relPanelSkill.getSkillTempCount().containsKey(skillInfo.getSkillName())
                &&relPanelSkill.getSkillTempCount().get(skillInfo.getSkillName())>0
                ?"§a§l+"+relPanelSkill.getSkillTempCount().get(skillInfo.getSkillName()):"";
        relLevelTextField.setText(textPre+level+temp);
    }


    private void initPlayerData() {
        this.playerDataRelClient = PlayerDataHandler.get(Lineage.proxy.getClientPlayer());
    }

    @Override
    public void onClicked(MouseButton button) {
        //忽视右键点击
        if (button.isRight())return;
        //建立快捷键关联
        buildSkillShortCutRelation();
        //在底部技能描述栏渲染技能等级、依赖、强度 等相关信息
        relPanelFootV2.setSkillDescription(buildDescString(skillInfo,playerDataRelClient));
    }

    public static String buildDescString(PlayerDataSkill skill,PlayerData playerDataLocal){
        if(null==skill)return "§l[空]";
        StringBuffer stringBuffer=new StringBuffer();
        stringBuffer.append("§l技能名：§6§l"+skill.getSkillName()).append("\n");
        stringBuffer.append("§l技能等级：§6§l"+skill.getSkillLevel()).append("\n");
        stringBuffer.append("§l技能升级需要点数：§6§l"+skill.getUpgradeCount()).append("\n");
        if(null!=playerDataLocal){
            if( skill.getLevelDependency()>playerDataLocal.getLevel()){
                stringBuffer.append("§l人物等级需求：§4§l"+skill.getLevelDependency()).append("\n");
            }else{
                stringBuffer.append("§l人物等级需求：§2§l"+skill.getLevelDependency()).append("\n");
            }
            if(skill.getSkillsDependencyName().isEmpty()){
                stringBuffer.append("§l依赖技能：§2§l无").append("\n");
            }else{
                stringBuffer.append("§l依赖技能：");
                for (String s : skill.getSkillsDependencyName()) {
                    if(playerDataLocal.sureSkillAvailable(s)){
                        stringBuffer.append("[§2§l"+s+"§r] ");
                    }else{
                        stringBuffer.append("[§4§l"+s+"§r] ");
                    }
                }
                stringBuffer.append("\n");
            }
            stringBuffer.append("§l技能描述：").append("\n")
                    .append(skill.defineSkillDesc()).append("\n");
        }else{
            stringBuffer.append("§l人物等级需求：").append(skill.getLevelDependency()).append("\n");
            stringBuffer.append("§l依赖技能：").append(skill.getSkillsDependencyName().toString()).append("\n");
            stringBuffer.append("§l技能描述：\n").append(skill.defineSkillDesc()).append("\n");
        }
        return stringBuffer.toString();
    }


    /**建立快捷键关联
     *
     */
    public void buildSkillShortCutRelation(){
        //不在快捷键编辑场景直接返回
        if(!relPanelSkill.getRelPanelSkillDescV2().ifSkillLookingFor())return;
        //非已经学习且可用的技能直接返回
        if (!skillInfo.isEnable())return;

        //查看是否存在当前技能已关联快捷键映射,若存在进行清除
        relPanelSkill.getRelPanelSkillDescV2().getSkillShortCutBtnList().stream()
                .filter(h->skillInfo.getSkillName().equals(h.getAssignSkillName())).forEach(v->{
                    v.setAssignSkillName(null);
                    v.setLookingFor(false);
                    v.setIcon(GuiIconsV2.skillChoiceEmpty);
                    v.setTitle("空");
                    //将关联信息,记录在玩家数据中,并进行服务器同步
            //消息:清理对应快捷键技能绑定.
            MessageSkillModify messageSkillModify  = new MessageSkillModify();
            messageSkillModify.writeClearTag(v.getIndex());
            //消息同步:清理对应快捷键技能绑定.
            NetworkHandler.INSTANCE.sendToServer(messageSkillModify);
        });
        //将正在查询的的快捷键绑定至当前技能
        Optional<PanelSkillDescV2.SkillShortCutBtn> skillShortCutBtn=
        relPanelSkill.getRelPanelSkillDescV2().getSkillShortCutBtnList().stream()
                .filter(h->h.isLookingFor()).findFirst();
        //防止空指针,若未能找到进行返回 TODO 一般情况该代码不会触发返回
        if(!skillShortCutBtn.isPresent())return;
        //规则:被动技能状态类型不允许绑定至快捷栏
        if(BaseConst.PLAYER_ADV_SEC_TAG__SKILLS_STATE.equals(skillInfo.getSkillSecondType())){
            mainGui.addLineToConsolePanel("§4被动技能 ["+skillInfo.getSkillName()+"] 无法关联至快捷键 "+skillShortCutBtn.get().getIndex());
        }else{
            skillShortCutBtn.get().setAssignSkillName(skillInfo.getSkillName());
            skillShortCutBtn.get().setTitle(skillInfo.getSkillName());
            skillShortCutBtn.get().setLookingFor(false);
            skillShortCutBtn.get().setIcon(skillInfo.getIcon());
            //将关联信息,记录在玩家数据中,并进行服务器同步
            //消息:对技能进行对应快捷键技能绑定.
            MessageSkillModify messageSkillModify  = new MessageSkillModify();
            messageSkillModify.write(skillInfo.getSkillName(),BaseConst.SkillOperate.bind_shortCut
                    ,skillShortCutBtn.get().getIndex());
            //消息同步:对技能进行对应快捷键技能绑定.
            NetworkHandler.INSTANCE.sendToServer(messageSkillModify);
            mainGui.addLineToConsolePanel("§6快捷键"+skillShortCutBtn.get().getIndex()+" 关联了技能["+skillInfo.getSkillName()+"]");
        }
    }




}
